package com.fary.aop.framework;

import com.fary.aop.Advisor;
import com.fary.aop.TargetClassAware;
import com.fary.aop.TargetSource;
import com.fary.core.SpringException;
import org.aopalliance.aop.Advice;

public interface Advised extends TargetClassAware {

	// Advised 配置是否冻结，冻结之后不能更改任何 Advice。
	boolean isFrozen();

	// 对应 @EnableAspectJAutoProxy 中的 proxyTargetClass 属性
	boolean isProxyTargetClass();

	// 返回由AOP代理代理的接口
	Class<?>[] getProxiedInterfaces();

	// 判断给定接口是否被代理
	boolean isInterfaceProxied(Class<?> intf);

	// 更改当前 Advised 对象使用的TargetSource，仅当配置不是 isFrozen 为 true 时有效。
	void setTargetSource(TargetSource targetSource);

	// 获取当前 Advised 对象使用的 TargetSource
	TargetSource getTargetSource();

	// 对应 @EnableAspectJAutoProxy 中的 exposeProxy 属性
	void setExposeProxy(boolean exposeProxy);

	// 返回工厂是否应该将代理暴露到 ThreadLocal（AopContext）。如果 Advise 的对象需要在应用 Advice 的情况下调用自身的方法，则有必要公开代理。
	// 否则，如果 Advice 的对象对此调用一个方法，则不会应用任何 Advice。获取代理类似于调用getEJBObject()的EJB。
	boolean isExposeProxy();

	// 设置此代理配置是否经过预过滤，以便仅包含可用的 Advisor (匹配此代理的目标类)。
	// 默认设置是 false。如果 Advisor 已经被预先过滤，则将其设置为 true，这意味着在为代理调用构建实际的 Advisor 链时可以跳过 ClassFilter 检查。
	void setPreFiltered(boolean preFiltered);

	// 返回此代理配置是否已预过滤，以便仅过滤包含可用的 Advisor (匹配此代理的目标类)。
	boolean isPreFiltered();

	// 返回应用于当前代理的 Advisor 列表
	Advisor[] getAdvisors();

	// 在 Advisor 链末尾添加 Advisor
	void addAdvisor(Advisor advisor) throws SpringException;

	// 在 Advisor 链指定的位置添加 Advisor
	void addAdvisor(int pos, Advisor advisor) throws SpringException;

	// 移除指定 Advisor
	boolean removeAdvisor(Advisor advisor);

	// 移除指定位置的 Advisor
	void removeAdvisor(int index) throws SpringException;

	// 检索 Advisor 在 Advisor 链中的位置
	int indexOf(Advisor advisor);

	// 替换指定 Advisor
	boolean replaceAdvisor(Advisor a, Advisor b) throws SpringException;

	// 添加 Advice 到 Advice 链末端（根据 Advice类型不同会被包装成 DefaultPointcutAdvisor或者 DefaultIntroductionAdvisor ）
	void addAdvice(Advice advice) throws SpringException;

	// 在 Advice 链指定的位置添加 Advisor
	void addAdvice(int pos, Advice advice) throws SpringException;

	// 移除指定 Advice
	boolean removeAdvice(Advice advice);

	// 检索 Advice 在 Advice 链中的位置
	int indexOf(Advice advice);

	// 代理配置的字符串描述
	String toProxyConfigString();

}